package com.zestinn.smart4j.framework.proxy;

import com.zestinn.smart4j.framework.annotation.Transaction;
import com.zestinn.smart4j.framework.helper.DatabaseHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;

/**
 * @author zestinn
 * @create 2017-09-26 10:48
 */
public class TransactionProxy implements Proxy{

    private static final Logger LOGGER = LoggerFactory.getLogger(TransactionProxy.class);

    private static final ThreadLocal<Boolean> FLAG_HOLDER = new ThreadLocal<Boolean>(){
        @Override
        protected Boolean initialValue(){
            return false;
        }
    };

    public Object doProxy(ProxyChain proxychain) throws Throwable {
        Object result;
        boolean flag = FLAG_HOLDER.get();

        Method method = proxychain.getTargetMethod();
        if (!flag && method.isAnnotationPresent(Transaction.class)){
            FLAG_HOLDER.set(true);
            try {
                DatabaseHelper.beginTransaction();
                LOGGER.debug("begin transaction!");
                result = proxychain.doProxyChain();
                DatabaseHelper.commitTransaction();
                LOGGER.debug("commit transaction");
            } catch (Exception e){
                DatabaseHelper.rollbackTransaction();
                LOGGER.debug("rollback transaction!");
                throw e;
            } finally {
                FLAG_HOLDER.remove();
            }
        } else {
            result = proxychain.doProxyChain();
        }
        return result;
    }
}
